<?php

namespace App\Services\Pay;

use App\Models\Common\PayWay;
use App\Models\Order\Transfers;
use GuzzleHttp\Client;
use Illuminate\Support\Facades\Log;
use WeSoonNet\LaravelPlus\Services\Com\SignService;

class PayService2
{
    private $http = null;
    private $host = null;

    public function __construct()
    {
        $this->http = new Client();
        $this->host = trim(env('PAY_SERVER_HOST'), '/');
    }


    /**
     * 查询交易订单
     *
     * @param  string  $gatewayName
     * @param  string  $trade_no
     *
     * @param  bool    $forced
     *
     * @param  string  $apikey
     *
     * @return mixed
     * @throws \Exception
     */
    public function query(string $gatewayName, string $trade_no, bool $forced = true, string $apikey = '')
    {
        $apikey = empty($apikey) ? '6c617e68-6320-11e9-89cf-acde48001122' : $apikey;
        $gatewayName  = strtolower($gatewayName);
        $data         = [
            'store_id' => $apikey,
            'trade_no' => $trade_no,
            'forced'   => (string) $forced,
        ];
        $data['sign'] = SignService::generate($data, $apikey);

        try
        {
            $response = $this->http->post("{$this->host}/api/pay/{$gatewayName}/query", [
                'form_params' => $data,
                'headers'     => [
                    'Accept' => 'application/json',
                ],
            ]);

            $result = json_decode((string) $response->getBody(), true);

            if(!$result['success']) throw new \Exception($result['message']);

            return $result['message'];
        }
        catch (\Exception $e)
        {
            Log::error('PayService error：' . $e->getMessage());

            throw new \Exception('支付服务端发生错误' . env('APP_DEBUG') ? $e->getMessage() : '');
        }
    }

    /**
     * 发起 POS 支付
     *
     * @param  string  $apikey
     * @param  string  $gatewayName
     * @param  string  $trade_no
     * @param  string  $code
     * @param  string  $subject
     * @param  float   $total_amount
     *
     * @return mixed
     * @throws \Exception
     */
    public function pos(string $gatewayName, string $trade_no, string $code, string $subject, float $total_amount, string $apikey='')
    {
        $apikey = empty($apikey) ? '6c617e68-6320-11e9-89cf-acde48001122' : $apikey;
        $gatewayName  = strtolower($gatewayName);
        $data         = [
            'store_id'     => $apikey,
            'trade_no'     => $trade_no,
            'subject'      => $subject,
            'total_amount' => (string) ($total_amount * 100),
            'auth_code'    => $code,
        ];
        $data['sign'] = SignService::generate($data, $apikey);

        try
        {
            $response = $this->http->post("{$this->host}/api/pay/{$gatewayName}/pos", [
                'form_params' => $data,
                'headers'     => [
                    'Accept' => 'application/json',
                ],
            ]);

            return json_decode((string) $response->getBody(), true);
        }
        catch (\Exception $e)
        {
            Log::error('PayService error：' . $e->getMessage());

            throw new \Exception('支付服务端发生错误' . env('APP_DEBUG') ? $e->getMessage() : '');
        }
    }

    /**
     * 发起 小程序 支付
     *
     * @param  string  $apikey
     * @param  string  $gatewayName
     * @param  string  $trade_no
     * @param  string  $openid
     * @param  string  $subject
     * @param  float   $total_amount
     *
     * @return mixed
     * @throws \Exception
     */
    public function miniAppPay(string $gatewayName, string $trade_no, string $openid, string $subject, float $total_amount, string $apikey='')
    {
        $apikey = empty($apikey) ? '6c617e68-6320-11e9-89cf-acde48001122' : $apikey;

        $gatewayName  = strtolower($gatewayName);
        $data         = [
            'store_id'     => $apikey,
            'trade_no'     => $trade_no,
            'subject'      => $subject,
            'total_amount' => (string) ($total_amount * 100),
            'openid'       => $openid,
        ];
        $data['sign'] = SignService::generate($data, $apikey);

        try
        {
            $response = $this->http->post("{$this->host}/api/pay/{$gatewayName}/miniapp", [
                'form_params' => $data,
                'headers'     => [
                    'Accept' => 'application/json',
                ],
            ]);

            $result = json_decode((string) $response->getBody(), true);

            if(!$result['success']) throw new \Exception($result['message']);

            return $result['message'];
        }
        catch (\Exception $e)
        {
            Log::error('PayService error：' . $e->getMessage());

            throw new \Exception('支付服务端发生错误' . env('APP_DEBUG') ? $e->getMessage() : '');
        }
    }

    /**
     * 发起 小程序 支付
     *
     * @param  string  $apikey
     * @param  string  $gatewayName
     * @param  string  $trade_no
     * @param  string  $subject
     * @param  float   $total_amount
     *
     * @return mixed
     * @throws \Exception
     */
    public function appPay(string $gatewayName, string $trade_no, string $subject, float $total_amount, string $apikey='')
    {
        $apikey = empty($apikey) ? '6c617e68-6320-11e9-89cf-acde48001122' : $apikey;

        $gatewayName  = strtolower($gatewayName);
        $data         = [
            'store_id'     => $apikey,
            'trade_no'     => $trade_no,
            'subject'      => $subject,
            'total_amount' => (string) ($total_amount * 100),
        ];
        $data['sign'] = SignService::generate($data, $apikey);

        try
        {
            $response = $this->http->post("{$this->host}/api/pay/{$gatewayName}/app", [
                'form_params' => $data,
                'headers'     => [
                    'Accept' => 'application/json',
                ],
            ]);

            $result = json_decode((string) $response->getBody(), true);

            if(!$result['success']) throw new \Exception($result['message']);

            return $result['message'];
        }
        catch (\Exception $e)
        {
            Log::error('PayService error：' . $e->getMessage());

            throw new \Exception('支付服务端发生错误' . env('APP_DEBUG') ? $e->getMessage() : '');
        }
    }


    /**
     * 发起 小程序 支付
     *
     * @param  string  $apikey
     * @param  string  $gatewayName
     * @param  string  $trade_no
     * @param  string  $subject
     * @param  float   $total_amount
     * @param  string  $openid
     * @param  bool    $check_name
     * @param  string  $name
     *
     * @return mixed
     * @throws \Exception
     */
    public function transfer(string $gatewayName, string $trade_no, string $subject, float $total_amount, string $openid, bool $check_name = false, string $name = '', string $apikey='')
    {
        $apikey = empty($apikey) ? '6c617e68-6320-11e9-89cf-acde48001122' : $apikey;

        $gatewayName  = strtolower($gatewayName);
        $data         = [
            'store_id'     => $apikey,
            'trade_no'     => $trade_no,
            'subject'      => $subject,
            'total_amount' => (string) ($total_amount * 100),
            'openid'       => $openid,
            'name'         => $name,
            'check_name'   => !$check_name ? 'NO_CHECK' : 'FORCE_CHECK',
        ];
        $data['sign'] = SignService::generate($data, $apikey);

        try
        {
            $response = $this->http->post("{$this->host}/api/pay/{$gatewayName}/transfer", [
                'form_params' => $data,
                'headers'     => [
                    'Accept' => 'application/json',
                ],
            ]);

            $data['state'] = 1;
            $data['return_data'] = (string) $response->getBody();

            Transfers::create($data);

            return json_decode((string) $response->getBody(), true);
        }
        catch (\Exception $e)
        {
            Log::error('PayService error：' . $e->getMessage());

            $data['state'] = 0;
            $data['return_data'] = $e->getMessage();

            Transfers::create($data);

            throw new \Exception('支付服务端发生错误' . env('APP_DEBUG') ? $e->getMessage() : '');
        }
    }

    /**
     * 退款
     *
     * @param  string  $apikey
     * @param  string  $gatewayName
     * @param  string  $trade_no
     * @param  string  $refund_no
     * @param  string  $refund_desc
     * @param  float   $refund_amount
     *
     * @return mixed
     * @throws \Exception
     */
    public function refund(string $gatewayName, string $trade_no, string $refund_no, string $refund_desc, float $refund_amount, string $apikey='')
    {
        $apikey = empty($apikey) ? '6c617e68-6320-11e9-89cf-acde48001122' : $apikey;

        $gatewayName  = strtolower($gatewayName);
        $data         = [
            'store_id'      => $apikey,
            'trade_no'      => $trade_no,
            'refund_no'     => $refund_no,
            'refund_amount' => (string) ($refund_amount * 100),
            'refund_desc'   => $refund_desc,
        ];
        $data['sign'] = SignService::generate($data, $apikey);

        try
        {
            $response = $this->http->post("{$this->host}/api/pay/{$gatewayName}/refund", [
                'form_params' => $data,
                'headers'     => [
                    'Accept' => 'application/json',
                ],
            ]);

            return json_decode((string) $response->getBody(), true);
        }
        catch (\Exception $e)
        {
            Log::error('PayService error：' . $e->getMessage());

            throw new \Exception('支付服务端发生错误' . env('APP_DEBUG') ? $e->getMessage() : '');
        }
    }

    //获取支付方式
    public static function payWay($key){
        return PayWay::find($key)->code;
    }
}
